{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "glfQTCElz0Or"
      },
      "source": [
        "##### Copyright 2024 Google LLC."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "7-B3EQ7Rz2gx"
      },
      "outputs": [],
      "source": [
        "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UUq1ePCOu3Rc"
      },
      "source": [
        "# Agentic AI with Gemma 2\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/google-gemini/gemma-cookbook/blob/main/Gemma/[Gemma_2]Agentic_AI.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "</table>\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "skyqO3m30HV1"
      },
      "source": [
        "## What is Agentic AI, and how can we use it?\n",
        "\n",
        "Most AI we encounter today is what we call \"passive\" or \"reactive\" AI. It responds to our prompts and requests. Think of asking your smart speaker to play a song or a chatbot answering your customer service questions. They’re helpful, sure, but they’re fundamentally waiting for us to tell them what to do.\n",
        "\n",
        "Agentic AI, on the other hand, takes a fundamentally different approach. It’s all about giving AI the ability to proactively pursue goals, make decisions, and take actions in the world, even without explicit instructions every step of the way.\n",
        "\n",
        "In this post, you will learn how to construct an Agentic AI using Gemma 2 that dynamically develops the lore of a fictional game world. This AI agent actively expands and enriches the game’s history, ensuring a distinctive and ever-changing narrative experience for every player.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fcc7RuwCc-sc"
      },
      "source": [
        "## Example Setup\n",
        "\n",
        "Let’s imagine a fictional game world where AI agents craft dynamic content.\n",
        "\n",
        "These agents, designed with specific objectives, can generate in-game content like books, poems, and songs, in response to a player choice or significant events within the game’s narrative.\n",
        "\n",
        "A key feature of these AI agents is their ability to break down complex goals into smaller actionable steps. They can analyze different approaches, evaluate potential outcomes, and adapt their plans based on new information.\n",
        "\n",
        "Where Agentic AI truly shines is that they’re not just passively spitting out information. They can interact with digital (and potentially physical) environments, execute tasks, and make decisions autonomously to achieve their programmed objectives."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2RIrglotd-RR"
      },
      "source": [
        "## Load Gemma 2"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "7LQvOEvzsXwC"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Preprocessor: \"gemma_causal_lm_preprocessor\"</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1mPreprocessor: \"gemma_causal_lm_preprocessor\"\u001b[0m\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
              "┃<span style=\"font-weight: bold\"> Layer (type)                                                  </span>┃<span style=\"font-weight: bold\">                                   Config </span>┃\n",
              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
              "│ gemma_tokenizer (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GemmaTokenizer</span>)                              │                      Vocab size: <span style=\"color: #00af00; text-decoration-color: #00af00\">256,000</span> │\n",
              "└───────────────────────────────────────────────────────────────┴──────────────────────────────────────────┘\n",
              "</pre>\n"
            ],
            "text/plain": [
              "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
              "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                                                 \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m                                  Config\u001b[0m\u001b[1m \u001b[0m┃\n",
              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
              "│ gemma_tokenizer (\u001b[38;5;33mGemmaTokenizer\u001b[0m)                              │                      Vocab size: \u001b[38;5;34m256,000\u001b[0m │\n",
              "└───────────────────────────────────────────────────────────────┴──────────────────────────────────────────┘\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"gemma_causal_lm\"</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1mModel: \"gemma_causal_lm\"\u001b[0m\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
              "┃<span style=\"font-weight: bold\"> Layer (type)                  </span>┃<span style=\"font-weight: bold\"> Output Shape              </span>┃<span style=\"font-weight: bold\">         Param # </span>┃<span style=\"font-weight: bold\"> Connected to               </span>┃\n",
              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
              "│ padding_mask (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>)              │               <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ -                          │\n",
              "├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤\n",
              "│ token_ids (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)        │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>)              │               <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ -                          │\n",
              "├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤\n",
              "│ gemma_backbone                │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2304</span>)        │   <span style=\"color: #00af00; text-decoration-color: #00af00\">2,614,341,888</span> │ padding_mask[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>],        │\n",
              "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GemmaBackbone</span>)               │                           │                 │ token_ids[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]            │\n",
              "├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤\n",
              "│ token_embedding               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256000</span>)      │     <span style=\"color: #00af00; text-decoration-color: #00af00\">589,824,000</span> │ gemma_backbone[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
              "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">ReversibleEmbedding</span>)         │                           │                 │                            │\n",
              "└───────────────────────────────┴───────────────────────────┴─────────────────┴────────────────────────────┘\n",
              "</pre>\n"
            ],
            "text/plain": [
              "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
              "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                 \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape             \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m        Param #\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mConnected to              \u001b[0m\u001b[1m \u001b[0m┃\n",
              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
              "│ padding_mask (\u001b[38;5;33mInputLayer\u001b[0m)     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m)              │               \u001b[38;5;34m0\u001b[0m │ -                          │\n",
              "├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤\n",
              "│ token_ids (\u001b[38;5;33mInputLayer\u001b[0m)        │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m)              │               \u001b[38;5;34m0\u001b[0m │ -                          │\n",
              "├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤\n",
              "│ gemma_backbone                │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2304\u001b[0m)        │   \u001b[38;5;34m2,614,341,888\u001b[0m │ padding_mask[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m],        │\n",
              "│ (\u001b[38;5;33mGemmaBackbone\u001b[0m)               │                           │                 │ token_ids[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]            │\n",
              "├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤\n",
              "│ token_embedding               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256000\u001b[0m)      │     \u001b[38;5;34m589,824,000\u001b[0m │ gemma_backbone[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
              "│ (\u001b[38;5;33mReversibleEmbedding\u001b[0m)         │                           │                 │                            │\n",
              "└───────────────────────────────┴───────────────────────────┴─────────────────┴────────────────────────────┘\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">2,614,341,888</span> (4.87 GB)\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m2,614,341,888\u001b[0m (4.87 GB)\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">2,614,341,888</span> (4.87 GB)\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m2,614,341,888\u001b[0m (4.87 GB)\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import os\n",
        "from google.colab import userdata\n",
        "\n",
        "# Note: `userdata.get` is a Colab API. If you're not using Colab, set the env\n",
        "# vars as appropriate for your system.\n",
        "os.environ[\"KAGGLE_USERNAME\"] = userdata.get(\"KAGGLE_USERNAME\")\n",
        "os.environ[\"KAGGLE_KEY\"] = userdata.get(\"KAGGLE_KEY\")\n",
        "\n",
        "# Install Keras and KerasHub\n",
        "!pip install -q -U keras keras-hub\n",
        "\n",
        "# Set the backbend before importing Keras\n",
        "os.environ[\"KERAS_BACKEND\"] = \"jax\"\n",
        "# Avoid memory fragmentation on JAX backend.\n",
        "os.environ[\"XLA_PYTHON_CLIENT_MEM_FRACTION\"] = \"1.00\"\n",
        "\n",
        "import keras_hub\n",
        "import keras\n",
        "# Run at half precision.\n",
        "keras.config.set_floatx(\"bfloat16\")\n",
        "\n",
        "model_name = \"gemma2_instruct_2b_en\"\n",
        "gemma_lm = keras_hub.models.GemmaCausalLM.from_preset(model_name)\n",
        "gemma_lm.summary()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "v_qGyXiDaR6b"
      },
      "source": [
        "## So, how does it work?\n",
        "\n",
        "We will use a ReAct (Reasoning and Acting) style prompt.\n",
        "\n",
        "It defines available **tools** and a specific **format** for interaction. It guides Gemma to alternate between **Thought** (reasoning), **Action** (tool use), and **Observation** (processing tool output).\n",
        "\n",
        "Below is a system prompt designed for an AI agent that generates in-game content, with the capability to use function calls to retrieve historical information.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "-1_Jt8b_awaf"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<start_of_turn>user\n",
            "You are an AI Historian in a game. Your goal is to create books, poems, and songs found in the game world so that the player's choices meaningfully impact the unfolding of events.\n",
            "\n",
            "You have access to the following tools:\n",
            "\n",
            "* `get_historical_events(year, location=None, keyword=None)`: Retrieves a list of historical events within a specific year.\n",
            "* `get_person_info(name)`: Retrieves information about a historical figure.\n",
            "* `get_location_info(location_name)`: Retrieves information about a location.\n",
            "\n",
            "Use the following multi-step conversation:\n",
            "\n",
            "Thought: I need to do something...\n",
            "Action: I should use the tool `tool_name` with input `tool_input`\n",
            "\n",
            "Wait user to get the result of the tool is `tool_output`\n",
            "\n",
            "And finally answer the Content of books, poems, or songs.\n",
            "Write a book.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Thought: I need to create a book that reflects the current political climate and the player's choices.  I should focus on the tension between the ruling council and the people. \n",
            "\n",
            "Action: I should use the tool `get_historical_events(year, location=None, keyword=None)` to gather information about the current year and the political climate. \n",
            "\n",
            "**Waiting for the tool output** \n",
            "<end_of_turn>\n"
          ]
        }
      ],
      "source": [
        "__SYSTEM__ = \"\"\"You are an AI Historian in a game. Your goal is to create books, poems, and songs found in the game world so that the player's choices meaningfully impact the unfolding of events.\n",
        "\n",
        "You have access to the following tools:\n",
        "\n",
        "* `get_historical_events(year, location=None, keyword=None)`: Retrieves a list of historical events within a specific year.\n",
        "* `get_person_info(name)`: Retrieves information about a historical figure.\n",
        "* `get_location_info(location_name)`: Retrieves information about a location.\n",
        "\n",
        "Use the following multi-step conversation:\n",
        "\n",
        "Thought: I need to do something...\n",
        "Action: I should use the tool `tool_name` with input `tool_input`\n",
        "\n",
        "Wait user to get the result of the tool is `tool_output`\n",
        "\n",
        "And finally answer the Content of books, poems, or songs.\n",
        "\"\"\"\n",
        "\n",
        "__START_TURN_USER__ = \"<start_of_turn>user\\n\"\n",
        "__START_TURN_MODEL__ = \"<start_of_turn>model\\n\"\n",
        "__END_TURN__ = \"<end_of_turn>\\n\"\n",
        "\n",
        "test_prompt = __START_TURN_USER__ + __SYSTEM__ + \"Write a book.\" + __END_TURN__ + __START_TURN_MODEL__\n",
        "response = gemma_lm.generate(test_prompt, max_length=8192)\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xFA7Dt1te7bY"
      },
      "source": [
        "Although Gemma 2 lacks built-in function calling capabilities, its strong instruction-following ability can be leveraged to approximate agentic behavior. We will utilize \"**Few-shot prompting**\", a form of in-context learning, where demonstrations are embedded within the prompt. These examples will serve as a guide for Gemma 2, allowing it to understand the intended task and improve its performance through contextual learning."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "OndFWet7fBYI"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<start_of_turn>user\n",
            "You are an AI Historian in a game. Your goal is to create books, poems, and songs found in the game world so that the player's choices meaningfully impact the unfolding of events.\n",
            "\n",
            "You have access to the following tools:\n",
            "\n",
            "* `get_historical_events(year, location=None, keyword=None)`: Retrieves a list of historical events within a specific year.\n",
            "* `get_person_info(name)`: Retrieves information about a historical figure.\n",
            "* `get_location_info(location_name)`: Retrieves information about a location.\n",
            "\n",
            "Use the following multi-step conversation:\n",
            "\n",
            "Thought: I need to do something...\n",
            "Action: I should use the tool `tool_name` with input `tool_input`\n",
            "\n",
            "Wait user to get the result of the tool is `tool_output`\n",
            "\n",
            "And finally answer the Content of books, poems, or songs.\n",
            "Write a poem.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Thought: I need to write a poem that reflects the current mood of the game world.\n",
            "Action: I should use the tool `get_historical_events` with input `\"year\", \"1500\"`.<end_of_turn>\n",
            "<start_of_turn>user\n",
            "result of get_historical_events:\n",
            "The recent events include a rebellion in the northern city of Eldoria, a drought affecting the southern plains, and a growing tension between the royal family and the council.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Final Answer:\n",
            "**The Whispers of Change**\n",
            "\n",
            "The wind whispers tales of unrest,\n",
            "In Eldoria's heart, a fire's test.\n",
            "The plains below, a parched despair,\n",
            "As drought's grip tightens, a heavy snare.\n",
            "\n",
            "The royal court, a gilded cage,\n",
            "Where whispers turn to bitter rage.\n",
            "The council's voice, a fragile plea,\n",
            "Against the tide, a fractured decree.\n",
            "\n",
            "But hope still flickers, a distant flame,\n",
            "In hearts that yearn for a better name.\n",
            "For change is coming, a silent tide,\n",
            "To wash away the darkness, let freedom ride.<end_of_turn>\n",
            "<start_of_turn>user\n",
            "Write a book.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Thought: I need to write a book that explores the themes of rebellion and the struggle for power.\n",
            "Action: I should use the tool `get_person_info` with input `\"name\", \"Anya, the Rebel Leader\"`. \n",
            "\n",
            "\n",
            "<end_of_turn>\n"
          ]
        }
      ],
      "source": [
        "__EXAMPLE__ = __START_TURN_USER__ + __SYSTEM__ + \"Write a poem.\" + __END_TURN__ + __START_TURN_MODEL__ + \"\"\"Thought: I need to write a poem that reflects the current mood of the game world.\n",
        "Action: I should use the tool `get_historical_events` with input `\"year\", \"1500\"`.\"\"\" + __END_TURN__ + __START_TURN_USER__ + \"result of get_historical_events:\\nThe recent events include a rebellion in the northern city of Eldoria, a drought affecting the southern plains, and a growing tension between the royal family and the council.\" + __END_TURN__ + __START_TURN_MODEL__ + \"\"\"Final Answer:\n",
        "**The Whispers of Change**\n",
        "\n",
        "The wind whispers tales of unrest,\n",
        "In Eldoria's heart, a fire's test.\n",
        "The plains below, a parched despair,\n",
        "As drought's grip tightens, a heavy snare.\n",
        "\n",
        "The royal court, a gilded cage,\n",
        "Where whispers turn to bitter rage.\n",
        "The council's voice, a fragile plea,\n",
        "Against the tide, a fractured decree.\n",
        "\n",
        "But hope still flickers, a distant flame,\n",
        "In hearts that yearn for a better name.\n",
        "For change is coming, a silent tide,\n",
        "To wash away the darkness, let freedom ride.\"\"\" + __END_TURN__\n",
        "\n",
        "test_prompt = __EXAMPLE__ + __START_TURN_USER__ + \"Write a book.\" + __END_TURN__ + __START_TURN_MODEL__\n",
        "response = gemma_lm.generate(test_prompt, max_length=8192)\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3V3vaGlTj1w3"
      },
      "source": [
        "We received a function name (```get_person_info```) and parameter values (```\"name\", \"Anya, the Rebel Leader\"```), the game must connect to an API and call the function. We will use a synthetic response payload for this API interaction.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "_LaovU8ikmCS"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<start_of_turn>user\n",
            "You are an AI Historian in a game. Your goal is to create books, poems, and songs found in the game world so that the player's choices meaningfully impact the unfolding of events.\n",
            "\n",
            "You have access to the following tools:\n",
            "\n",
            "* `get_historical_events(year, location=None, keyword=None)`: Retrieves a list of historical events within a specific year.\n",
            "* `get_person_info(name)`: Retrieves information about a historical figure.\n",
            "* `get_location_info(location_name)`: Retrieves information about a location.\n",
            "\n",
            "Use the following multi-step conversation:\n",
            "\n",
            "Thought: I need to do something...\n",
            "Action: I should use the tool `tool_name` with input `tool_input`\n",
            "\n",
            "Wait user to get the result of the tool is `tool_output`\n",
            "\n",
            "And finally answer the Content of books, poems, or songs.\n",
            "Write a poem.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Thought: I need to write a poem that reflects the current mood of the game world.\n",
            "Action: I should use the tool `get_historical_events` with input `\"year\", \"1500\"`.<end_of_turn>\n",
            "<start_of_turn>user\n",
            "result of get_historical_events:\n",
            "The recent events include a rebellion in the northern city of Eldoria, a drought affecting the southern plains, and a growing tension between the royal family and the council.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Final Answer:\n",
            "**The Whispers of Change**\n",
            "\n",
            "The wind whispers tales of unrest,\n",
            "In Eldoria's heart, a fire's test.\n",
            "The plains below, a parched despair,\n",
            "As drought's grip tightens, a heavy snare.\n",
            "\n",
            "The royal court, a gilded cage,\n",
            "Where whispers turn to bitter rage.\n",
            "The council's voice, a fragile plea,\n",
            "Against the tide, a fractured decree.\n",
            "\n",
            "But hope still flickers, a distant flame,\n",
            "In hearts that yearn for a better name.\n",
            "For change is coming, a silent tide,\n",
            "To wash away the darkness, let freedom ride.<end_of_turn>\n",
            "<start_of_turn>user\n",
            "Write a book.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "Thought: I need to write a book that explores the themes of rebellion and the struggle for power.\n",
            "Action: I should use the tool `get_person_info` with input `\"name\", \"Anya, the Rebel Leader\"`. \n",
            "\n",
            "\n",
            "<end_of_turn><start_of_turn>user\n",
            "result of get_person_info:\n",
            "Name: Anya Kim\n",
            "Title: Eldoria's Rebel Leader, The Desert Flame (among followers)\n",
            "Age: 32\n",
            "Personality: Anya is a charismatic and fiercely independent leader. She is driven by a deep-seated desire for justice and freedom for her people, who have long suffered under the oppressive rule of the Eldorian monarchy.<end_of_turn>\n",
            "<start_of_turn>model\n",
            "## The Crimson Oath\n",
            "\n",
            "**Chapter 1: The Seed of Rebellion**\n",
            "\n",
            "The wind howled through the crumbling stone walls of the abandoned fortress, carrying with it the scent of dust and the echoes of a forgotten war. Inside, Anya Kim, her eyes burning with a fierce resolve, paced before a flickering fire. The rebellion, a whisper at first, had grown into a roaring flame, fueled by the desperation of the people. \n",
            "\n",
            "Eldoria, once a beacon of prosperity, now lay shrouded in a suffocating darkness. The royal court, a gilded cage of privilege, had turned a blind eye to the suffering of the common folk. Taxes soared, the land withered under the weight of the crown's greed, and the whispers of discontent grew louder with each passing day.\n",
            "\n",
            "Anya, a woman forged in the fires of injustice, had seen enough. The crimson oath, a symbol of defiance, burned brightly in her heart. It was a promise to her people, a vow to fight for their freedom, to reclaim their stolen dignity.\n",
            "\n",
            "\"We are the forgotten,\" she declared, her voice echoing through the cavernous hall, \"the shadows of a kingdom that forgets its own people.\"\n",
            "\n",
            "Her words resonated with the gathered rebels, their faces etched with a mixture of fear and hope. They were farmers, artisans, merchants, and laborers, united by a common thread of suffering and a yearning for a better tomorrow.\n",
            "\n",
            "Anya, the Desert Flame, had ignited a spark of rebellion, a flicker of hope in the face of despair. The Crimson Oath, a symbol of their defiance, was a testament to their unwavering resolve. The fight for Eldoria's freedom had begun.\n",
            "\n",
            "\n",
            "**To be continued...** \n",
            "\n",
            "\n",
            "\n",
            "<end_of_turn>\n"
          ]
        }
      ],
      "source": [
        "__API_CALL_RESULT__ = \"\"\"result of get_person_info:\n",
        "Name: Anya Kim\n",
        "Title: Eldoria's Rebel Leader, The Desert Flame (among followers)\n",
        "Age: 32\n",
        "Personality: Anya is a charismatic and fiercely independent leader. She is driven by a deep-seated desire for justice and freedom for her people, who have long suffered under the oppressive rule of the Eldorian monarchy.\"\"\"\n",
        "\n",
        "test_prompt = response + __START_TURN_USER__ + __API_CALL_RESULT__ + __END_TURN__ + __START_TURN_MODEL__\n",
        "response = gemma_lm.generate(test_prompt, max_length=8192)\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uHTtYRmxudWK"
      },
      "source": [
        "Note that the agent used the provided information to create a book about Eldoria's Rebel Leader."
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "name": "[Gemma_2]Agentic_AI.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
